// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.utils;

//import com.aspose.words.*;
//import com.aspose.words.HeaderFooter;
//import com.aspose.words.HorizontalAlignment;
//import com.aspose.words.Paragraph;
//import com.aspose.words.Section;
//import com.aspose.words.VerticalAlignment;
//import com.itextpdf.text.Document;
//import com.itextpdf.text.Font;

import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.modules.entity.User;
import com.itextpdf.text.Image;
//import com.itextpdf.text.*;
//import com.itextpdf.text.pdf.*;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class PdfUtils {

    public static void createTableCell(String text, Font font, PdfPTable table, float lineHeight, int colSapn) {
        PdfPCell cell;
        cell = new PdfPCell(new Paragraph(text, font));
        //合并单元格列
        cell.setColspan(colSapn);
        //设置水平居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        //设置垂直居中
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(lineHeight);
        //将单元格内容添加到表格中
        table.addCell(cell);
    }

    public static void createTableCellLeft(String text, Font font, PdfPTable table, float lineHeight, int colSapn) {
        PdfPCell cell;
        cell = new PdfPCell(new Paragraph(text, font));
        //合并单元格列
        cell.setColspan(colSapn);
        //设置水平
        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
        //设置垂直
        cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
        cell.setFixedHeight(lineHeight);
        cell.setBorderWidthRight(0);
        cell.setBorderWidthBottom(0);
        cell.setBorderWidthLeft(0);
        cell.setBorderWidthTop(0);
        //将单元格内容添加到表格中
        table.addCell(cell);
    }

    public static void createTableCellCenter(String text, Font font, PdfPTable table, float lineHeight, int colSapn) {
        PdfPCell cell;
        cell = new PdfPCell(new Paragraph(text, font));
        //合并单元格列
        cell.setColspan(colSapn);
        //设置水平居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        //设置垂直居中
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setFixedHeight(lineHeight);
        cell.setBorderWidthLeft(0);
        cell.setBorderWidthRight(0);
        cell.setBorderWidthBottom(0);
        cell.setBorderWidthTop(0);

        //将单元格内容添加到表格中
        table.addCell(cell);

    }

    public static void createTableCellRight(String text, Font font, PdfPTable table, float lineHeight, int colSapn) {
        PdfPCell cell;
        cell = new PdfPCell(new Paragraph(text, font));
        //合并单元格列
        cell.setColspan(colSapn);
        //设置水平
        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
        //设置垂直
        cell.setVerticalAlignment(Element.ALIGN_TOP);
        cell.setFixedHeight(lineHeight);
        //将单元格内容添加到表格中
        //去除边框
        cell.setBorderWidthLeft(0);
        cell.setBorderWidthBottom(0);
        cell.setBorderWidthRight(0);
        cell.setBorderWidthTop(0);
        table.addCell(cell);
    }

    public static List<Map<String, Object>> getResult() {
        List<Map<String, Object>> result = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("dateTime", "2022/10/11");
            map.put("creator", "行如火");
            map.put("createTime", "2022/10/10");
            map.put("updator", "疾如风");
            map.put("updateTime", "2022/10/11");
            if (i == 0) {
                map.put("status", "0");
                map.put("description", "测试导出PDF");
            } else if (i < 4) {
                map.put("status", "1");
                map.put("description", "测试导出PDF" + i);
            } else {
                map.put("status", "2");
                map.put("description", "测试导出PDF" + i);
            }
            result.add(map);
        }
        System.out.println(result);
        return result;
    }

    /**
     * 无模板导出PDF
     *
     * @param fileName 导出文件名
     * @param response 返回响应
     * @param data     要打包的数据
     * @param type     类型 1.项目 2.专利风险分析
     */
    public static void generatePDFDoc(String fileName, HttpServletResponse response, Map<String, Object> data, int type) {
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 设置响应头
        response.setContentType("application/force-download");
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".pdf");
        OutputStream out = null;
        Document doc = new Document(PageSize.A4);
        try {
            out = response.getOutputStream();
            PdfWriter writer = PdfWriter.getInstance(doc, out);
            doc.open();
            doc = type == 1 ? makeProjectPDF(doc, data) : makeProjectPatentPDF(doc, data);

//            BaseFont bfChinese = null;
//            try {
//                bfChinese=BaseFont.createFont()
//            }
            BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            PdfContentByte waterMar = writer.getDirectContentUnder();
            User user = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
            String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
            String text = user.getName() + " " + user.getSn() + " " +currentTime;
            addTextFullWaterMark(waterMar, text, bf);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭文档
            if (doc != null) {
                doc.close();
            }
            try {
                if (out != null) {
                    out.flush();
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 生成项目专利风险信息文档
     *
     * @param data 数据键值对，根据实际情况修改键名称
     * @return 文档
     */
    private static Document makeProjectPatentPDF(Document doc, Map<String, Object> data) {
        try {
            BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font font = new Font(bf, 10, Font.NORMAL, BaseColor.BLACK);
            Font fontTile = new Font(bf, 14, Font.BOLD, BaseColor.BLACK);
            Paragraph paragraph1 = new Paragraph("新产品专利风险分析报告", fontTile);
            paragraph1.setAlignment(PdfPCell.ALIGN_CENTER);
            //设置行间距
            paragraph1.setLeading(15f);
            //设置段落下空白
            paragraph1.setSpacingAfter(20f);

            // 下载信息
            Font exportFont = new Font(bf, 8, Font.NORMAL, BaseColor.BLACK);
            PdfPTable exportText = new PdfPTable(new float[]{2f, 2f, 2f, 2f, 2f, 2f});
            exportText.addCell(createCell("", exportFont,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 4, 0, 15));
            exportText.addCell(createCell((String) data.get("operateUser"), exportFont,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));
            exportText.addCell(createCell((String) data.get("operateTime"), exportFont,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));
            //增加空行
            exportText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 3, 15));

            // 项目信息
            PdfPTable tbText = new PdfPTable(new float[]{2.5f, 2f, 2.5f, 2f, 2.5f, 2f});
            tbText.addCell(createCell("项目信息", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 1, 15));
            //增加空行
            tbText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 1, 15));
            // 项目信息数据
            tbText.addCell(createCell("项目名称：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 1, 1, 15));
            tbText.addCell(createCell(ObjectUtils.isEmpty(data.getOrDefault("projectName", " ")) ? " " :
                            data.getOrDefault("projectName", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 5, 1, 15));
            tbText.addCell(createCell("项目等级：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(ObjectUtils.isEmpty(data.getOrDefault("projectLevelName", " ")) ? " " :
                            data.getOrDefault("projectLevelName", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));
            tbText.addCell(createCell("项目类型：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(ObjectUtils.isEmpty(data.getOrDefault("projectTypeName", " ")) ? " " :
                            data.getOrDefault("projectTypeName", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));
            tbText.addCell(createCell("所属部门：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("projectDepartmentName", " ") == null ? " " :
                            data.getOrDefault("projectDepartmentName", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell("立项编号：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("projectSn", " ") == null ? " " :
                            data.getOrDefault("projectSn", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell("财务项目号：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("projectFinancialSn", " ") == null ? " " :
                            data.getOrDefault("projectFinancialSn", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell("项目状态：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("statusName", " ") == null ? " " :
                            data.getOrDefault("statusName", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell("项目经理：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("projectManagerName", " ") == null ? " " :
                            data.getOrDefault("projectManagerName", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));

            tbText.addCell(createCell("立项日期：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("startDate", " ") == null ? " " :
                            StringUtils.isEmpty(data.getOrDefault("startDate", "").toString()) ? "" : data.getOrDefault("startDate", " ").toString().substring(0, 10), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));
            tbText.addCell(createCell("计划完成日期：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("endDate", " ") == null ? " " :
                            StringUtils.isEmpty(data.getOrDefault("endDate", "").toString()) ? "" : data.getOrDefault("endDate", "").toString().substring(0, 10), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));
            //增加空行
            tbText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 3, 15));

            // 设计差异点清单
            List<Map<String, Object>> riskDataList = (List<Map<String, Object>>) data.get("riskDataList");
            PdfPTable riskText = new PdfPTable(new float[]{1f, 1.5f, 1f, 0.8f, 1.6f, 3f});
            riskText.addCell(createCell("设计差异点", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 1, 15));
            //增加空行
            riskText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 1, 15));

            PdfPTable riskTable = new PdfPTable(new float[]{1f, 2f, 1.5f, 1.5f, 2f});
            //表头
            riskTable.addCell(createCell("序号", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            riskTable.addCell(createCell("设计差异点描述", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            riskTable.addCell(createCell("比对的基础型号", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            riskTable.addCell(createCell("设计差异点图示", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            riskTable.addCell(createCell("检索结论", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));

            //动态表格
            int riskSort = 1;
            if (!ObjectUtils.isEmpty(riskDataList)) {
                for (Map<String, Object> risk : riskDataList) {
                    riskTable.addCell(createCell(String.valueOf(riskSort), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    riskTable.addCell(createCell(risk.getOrDefault("riskName", " ") == null ? " " :
                                    risk.getOrDefault("riskName", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    riskTable.addCell(createCell(risk.getOrDefault("referenceModel", " ") == null ? " " :
                                    risk.getOrDefault("referenceModel", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));

                    if (risk.getOrDefault("pictureUrl", " ") != null) {
                        try {
                            PdfPCell cell = new PdfPCell();
                            List<Map<String, Object>> pictureList = (List<Map<String, Object>>) risk.getOrDefault("pictureUrl", new ArrayList<>());
                            Map<String, Object> pictureMap = pictureList.get(0);
                            String url = "uploadLocal/" + pictureMap.get("id") + "." + pictureMap.get("fileType");
                            Image image = Image.getInstance(url);
                            image.scaleAbsolute(40, 40);
                            cell.addElement(image);
                            riskTable.addCell(cell);
                        } catch (Exception e) {
                            e.printStackTrace();
                            riskTable.addCell(createCell(" ", font,
                                    Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                        }
                    } else {
                        riskTable.addCell(createCell(risk.getOrDefault("pictureUrl", " ") == null ? " " :
                                        risk.getOrDefault("pictureUrl", " ").toString(), font,
                                Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    }
//                    riskTable.addCell(createCell(risk.getOrDefault("pictureUrl", " ") == null ? " " :
//                                    risk.getOrDefault("pictureUrl", " ").toString(), font,
//                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    riskTable.addCell(createCell(risk.getOrDefault("searchConclusion", " ") == null ? " " :
                                    risk.getOrDefault("searchConclusion", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    riskSort++;
                }
            }

            // 风险管控记录
            List<Map<String, Object>> processList = (List<Map<String, Object>>) data.get("processList");
            PdfPTable processText = new PdfPTable(new float[]{1f, 1.5f, 1f, 0.8f, 1.6f, 3f});
            //增加空行
            processText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 3, 15));
            processText.addCell(createCell("风险管控记录", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 2, 15));
            //增加空行
            processText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 1, 15));
            PdfPTable processTable = new PdfPTable(new float[]{1f, 2f, 1.5f, 2f, 2.5f});
            //表头
            processTable.addCell(createCell("序号", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            processTable.addCell(createCell("阶段", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            processTable.addCell(createCell("状态", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            processTable.addCell(createCell("最近操作时间", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            processTable.addCell(createCell("评估信息", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));

            //动态表格
            int processSort = 1;
            if (!ObjectUtils.isEmpty(processList)) {
                for (Map<String, Object> plan : processList) {
                    processTable.addCell(createCell(String.valueOf(processSort), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    processTable.addCell(createCell(plan.getOrDefault("title", " ") == null ? " " :
                                    plan.getOrDefault("title", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    processTable.addCell(createCell(plan.getOrDefault("statusName", " ") == null ? " " :
                                    plan.getOrDefault("statusName", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    processTable.addCell(createCell(plan.getOrDefault("description", " ") == null ? " " :
                                    plan.getOrDefault("description", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    processTable.addCell(createCell(plan.getOrDefault("subTitle", " ") == null ? " " :
                                    plan.getOrDefault("subTitle", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    processSort++;
                }
            }

            // 签批记录清单
            List<Map<String, Object>> workflowList = (List<Map<String, Object>>) data.get("workflowDataList");
            PdfPTable workflowText = new PdfPTable(new float[]{1f, 1.5f, 1f, 0.8f, 1.6f, 3f});
            workflowText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 2, 15));
            workflowText.addCell(createCell("签批记录", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 2, 15));
            // 增加空行
            workflowText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 1, 15));
            PdfPTable workflowTable = new PdfPTable(new float[]{1f, 2f, 2f, 2f, 2f});
            // 表头
            workflowTable.addCell(createCell("序号", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            workflowTable.addCell(createCell("流程类型", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            workflowTable.addCell(createCell("发起人", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            workflowTable.addCell(createCell("流程状态", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            workflowTable.addCell(createCell("操作时间", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));

            //动态表格
            int workflowSort = 1;
            if (!ObjectUtils.isEmpty(workflowList)) {
                for (Map<String, Object> work : workflowList) {
                    workflowTable.addCell(createCell(String.valueOf(workflowSort), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    workflowTable.addCell(createCell(work.getOrDefault("flowTypeName", " ") == null ? " " :
                                    work.getOrDefault("flowTypeName", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    workflowTable.addCell(createCell(work.getOrDefault("operateUser", " ") == null ? " " :
                                    work.getOrDefault("operateUser", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    workflowTable.addCell(createCell(work.getOrDefault("statusName", " ") == null ? " " :
                                    work.getOrDefault("statusName", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    workflowTable.addCell(createCell(work.getOrDefault("updateTime", " ") == null ? " " :
                                    work.getOrDefault("updateTime", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    workflowSort++;
                }
            }

            doc.add(paragraph1);
            doc.add(exportText);
            doc.add(tbText);
            doc.add(riskText);
            doc.add(riskTable);
            doc.add(processText);
            doc.add(processTable);
            doc.add(workflowText);
            doc.add(workflowTable);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return doc;
    }

    /**
     * @param value               文本
     * @param font                字体
     * @param horizontalAlignment 水平样式 0-left, 1-center, 2-right
     * @param verticalAlignment   垂直样式  4-top, 5-middle, 6-bottom;
     * @param colspan             列合并
     * @param rowspan             行合并
     * @param borderSide          外边框
     *                            0-默认
     *                            1-隐藏上边框
     *                            2-隐藏下边框
     *                            3-隐藏上、下边框
     *                            4-隐藏左边框
     *                            5-隐藏左、上边框
     *                            6-隐藏左、下边框
     *                            7-隐藏左、上、下边框
     *                            8-隐藏右边框
     *                            9-隐藏右、上边框
     *                            10-隐藏右、下边框
     *                            11-隐藏右、上、下边框
     *                            12-隐藏左、右边框
     *                            13-隐藏上、左、右边框
     *                            14-隐藏下、左、右边框
     *                            15-隐藏全部
     * @return
     */
    public static PdfPCell createCell(String value, Font font, int horizontalAlignment, int verticalAlignment, int colspan, int rowspan, int borderSide) {
        PdfPCell cell = new PdfPCell();
        cell.setPhrase(new Phrase(value, font));
        //水平居中
        cell.setHorizontalAlignment(horizontalAlignment);
        if (verticalAlignment > 0) {
            //垂直居中
            cell.setUseAscender(true);
        }
        //垂直居中
        cell.setVerticalAlignment(verticalAlignment);
        if (colspan > 0) {
            cell.setColspan(colspan);
        }
        if (rowspan > 0) {
            cell.setRowspan(rowspan);
        }
        if (borderSide > 0) {
            cell.disableBorderSide(borderSide);
        }
        return cell;
    }

    /**
     * 生成项目信息文档
     *
     * @param data 数据键值对，根据实际情况修改键名称
     * @return 文档
     */
    private static Document makeProjectPDF(Document doc, Map<String, Object> data) {
        try {
            BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font font = new Font(bf, 12, Font.NORMAL, BaseColor.BLACK);
            Font fontTile = new Font(bf, 14, Font.BOLD, BaseColor.BLACK);
            Paragraph paragraph1 = new Paragraph("项目信息", fontTile);
            paragraph1.setAlignment(PdfPCell.ALIGN_CENTER);
            //设置行间距
            paragraph1.setLeading(15f);
            //设置段落下空白
            paragraph1.setSpacingAfter(20f);

            PdfPTable tbText = new PdfPTable(new float[]{1f, 2f, 1f, 2f});
            tbText.addCell(createCell("项目名称：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(ObjectUtils.isEmpty(data.getOrDefault("projectName", " ")) ? " " :
                            data.getOrDefault("projectName", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));
            tbText.addCell(createCell("当前状态：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("statusName", " ") == null ? " " :
                            data.getOrDefault("statusName", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell("项目经理：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("projectManagerName", " ") == null ? " " :
                            data.getOrDefault("projectManagerName", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));
            tbText.addCell(createCell("责任部门：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("departmentName", " ") == null ? " " :
                            data.getOrDefault("departmentName", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell("开始日期：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("startDate", " ") == null ? " " :
                            data.getOrDefault("startDate", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));
            tbText.addCell(createCell("截止日期：", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 0, 0, 15));
            tbText.addCell(createCell(data.getOrDefault("endDate", " ") == null ? " " :
                            data.getOrDefault("endDate", " ").toString(), font,
                    PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0, 0, 15));
            //增加空行
            tbText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 2, 15));

            // 项目技术难点清单
            List<Map<String, Object>> difficultyList = (List<Map<String, Object>>) data.get("difficultyList");
            PdfPTable difficultyText = new PdfPTable(new float[]{1f, 1.5f, 1f, 0.8f, 1.6f, 3f});
            difficultyText.addCell(createCell("项目技术难点清单", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 2, 15));
            PdfPTable difficultyTable = new PdfPTable(new float[]{1f, 2f, 1.5f, 1.5f, 2f, 2f, 2f, 2f});
            //表头
            difficultyTable.addCell(createCell("序号", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            difficultyTable.addCell(createCell("技术难点", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            difficultyTable.addCell(createCell("状态", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            difficultyTable.addCell(createCell("责任人", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            difficultyTable.addCell(createCell("协助专家", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            difficultyTable.addCell(createCell("难点描述", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            difficultyTable.addCell(createCell("截止日期", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            difficultyTable.addCell(createCell("完成情况", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));

            //动态表格
            int difficultySort = 1;
            if (!ObjectUtils.isEmpty(difficultyList)) {
                for (Map<String, Object> difficulty : difficultyList) {
                    difficultyTable.addCell(createCell(String.valueOf(difficultySort), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    difficultyTable.addCell(createCell(difficulty.getOrDefault("difficultyName", " ") == null ? " " :
                                    difficulty.getOrDefault("difficultyName", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    difficultyTable.addCell(createCell(difficulty.getOrDefault("statusName", " ") == null ? " " :
                                    difficulty.getOrDefault("statusName", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    difficultyTable.addCell(createCell(difficulty.getOrDefault("ownerName", " ") == null ? " " :
                                    difficulty.getOrDefault("ownerName", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    difficultyTable.addCell(createCell(difficulty.getOrDefault("expertList", " ") == null ? " " :
                                    difficulty.getOrDefault("expertList", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    difficultyTable.addCell(createCell(difficulty.getOrDefault("remark", " ") == null ? " " :
                                    difficulty.getOrDefault("remark", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    difficultyTable.addCell(createCell(difficulty.getOrDefault("expiryDate", " ") == null ? " " :
                                    difficulty.getOrDefault("expiryDate", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    difficultyTable.addCell(createCell(difficulty.getOrDefault("finishRate", " ") == null ? " " :
                                    difficulty.getOrDefault("finishRate", "0").toString() + "%", font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    difficultySort++;
                }
            }

            // 专家方案清单
            List<Map<String, Object>> planList = (List<Map<String, Object>>) data.get("difficultyPlanList");
            PdfPTable planText = new PdfPTable(new float[]{1f, 1.5f, 1f, 0.8f, 1.6f, 3f});
            //增加空行
            planText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 2, 15));
            planText.addCell(createCell("专家方案清单", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 2, 15));
            PdfPTable planTable = new PdfPTable(new float[]{1f, 2f, 1.5f, 2f, 2.5f, 2.5f});
            //表头
            planTable.addCell(createCell("序号", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            planTable.addCell(createCell("技术难点", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            planTable.addCell(createCell("提出专家", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            planTable.addCell(createCell("提出日期", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            planTable.addCell(createCell("方案内容", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            planTable.addCell(createCell("方案反馈", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));

            //动态表格
            int planSort = 1;
            if (!ObjectUtils.isEmpty(planList)) {
                for (Map<String, Object> plan : planList) {
                    planTable.addCell(createCell(String.valueOf(planSort), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    planTable.addCell(createCell(plan.getOrDefault("difficultyName", " ") == null ? " " :
                                    plan.getOrDefault("difficultyName", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    planTable.addCell(createCell(plan.getOrDefault("expertName", " ") == null ? " " :
                                    plan.getOrDefault("expertName", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    planTable.addCell(createCell(plan.getOrDefault("suggestTime", " ") == null ? " " :
                                    plan.getOrDefault("suggestTime", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    planTable.addCell(createCell(plan.getOrDefault("content", " ") == null ? " " :
                                    plan.getOrDefault("content", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    planTable.addCell(createCell(plan.getOrDefault("feedbackInfo", " ") == null ? " " :
                                    plan.getOrDefault("feedbackInfo", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    planSort++;
                }
            }

            // 项目风险点清单
            List<Map<String, Object>> riskList = (List<Map<String, Object>>) data.get("riskList");
            PdfPTable riskText = new PdfPTable(new float[]{1f, 1.5f, 1f, 0.8f, 1.6f, 3f});
            riskText.addCell(createCell(" ", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 2, 15));
            riskText.addCell(createCell("项目风险点清单", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_LEFT, 6, 2, 15));
            PdfPTable riskTable = new PdfPTable(new float[]{1f, 2f, 2f, 2f, 2f});
            //表头
            riskTable.addCell(createCell("序号", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            riskTable.addCell(createCell("风险点名称", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            riskTable.addCell(createCell("提出专家", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            riskTable.addCell(createCell("风险点描述", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
            riskTable.addCell(createCell("截止日期", font, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));

            //动态表格
            int riskSort = 1;
            if (!ObjectUtils.isEmpty(riskList)) {
                for (Map<String, Object> risk : riskList) {
                    riskTable.addCell(createCell(String.valueOf(riskSort), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    riskTable.addCell(createCell(risk.getOrDefault("difficultyName", " ") == null ? " " :
                                    risk.getOrDefault("difficultyName", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    riskTable.addCell(createCell(risk.getOrDefault("expertList", " ") == null ? " " :
                                    risk.getOrDefault("expertList", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    riskTable.addCell(createCell(risk.getOrDefault("remark", " ") == null ? " " :
                                    risk.getOrDefault("remark", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    riskTable.addCell(createCell(risk.getOrDefault("expiryDate", " ") == null ? " " :
                                    risk.getOrDefault("expiryDate", " ").toString(), font,
                            Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 0, 0, 0));
                    riskSort++;
                }
            }

            doc.add(paragraph1);
            doc.add(tbText);
            doc.add(difficultyText);
            doc.add(difficultyTable);
            doc.add(planText);
            doc.add(planTable);
            doc.add(riskText);
            doc.add(riskTable);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return doc;
    }


    public static void addTextFullWaterMark(PdfContentByte waterMar, String text, BaseFont bf) {
        waterMar.beginText();
        PdfGState gs = new PdfGState();
        gs.setFillOpacity(0.1f);
        waterMar.setFontAndSize(bf, 10);

        for (int x = -50; x <= 900; x += 150) {
            for (int y = -50; y <= 800; y += 150) {
                waterMar.showTextAligned(Element.ALIGN_RIGHT, text, x, y, 25);
            }
        }
        waterMar.setColorFill(BaseColor.LIGHT_GRAY);
        waterMar.endText();
        waterMar.stroke();
    }
}
